<template>
  <div class="menu-list-container">
    <el-card class="page-header">
      <h2>菜单管理</h2>
      <p>管理系统中的菜单结构和权限</p>
    </el-card>
    
    <el-card class="search-section">
      <el-form :inline="true" :model="searchForm">
        <el-form-item label="菜单名称">
          <el-input v-model="searchForm.menuName" placeholder="请输入菜单名称"></el-input>
        </el-form-item>
        <el-form-item label="菜单类型">
          <el-select v-model="searchForm.menuType" placeholder="请选择菜单类型">
            <el-option label="全部" value=""></el-option>
            <el-option label="目录" value="0"></el-option>
            <el-option label="菜单" value="1"></el-option>
            <el-option label="按钮" value="2"></el-option>
          </el-select>
        </el-form-item>
        <el-form-item label="状态">
          <el-select v-model="searchForm.status" placeholder="请选择状态">
            <el-option label="全部" value=""></el-option>
            <el-option label="启用" value="1"></el-option>
            <el-option label="禁用" value="0"></el-option>
          </el-select>
        </el-form-item>
        <el-form-item>
          <el-button type="primary" @click="searchMenus">搜索</el-button>
          <el-button @click="resetSearch">重置</el-button>
          <el-button type="success" @click="handleCreateMenu">新增菜单</el-button>
        </el-form-item>
      </el-form>
    </el-card>
    
    <el-card class="data-table">
      <div class="tree-table-container">
        <el-tree-table 
          ref="menuTreeTableRef"
          :data="menuTreeData" 
          row-key="id" 
          parent-key="parentId" 
          border 
          default-expand-all
          style="width: 100%"
        >
          <el-table-column prop="menuName" label="菜单名称" min-width="180">
            <template #default="scope">
              <div style="display: flex; align-items: center; gap: 8px;">
                <el-icon v-if="scope.row.menuType === '0' || scope.row.menuType === 0">
                  <Folder />
                </el-icon>
                <el-icon v-else-if="scope.row.menuType === '1' || scope.row.menuType === 1">
                  <Menu />
                </el-icon>
                <el-icon v-else-if="scope.row.menuType === '2' || scope.row.menuType === 2">
                  <Operation />
                </el-icon>
                <span>{{ scope.row.menuName }}</span>
              </div>
            </template>
          </el-table-column>
          <el-table-column prop="menuType" label="菜单类型" width="100" align="center">
            <template #default="scope">
              <el-tag v-if="scope.row.menuType === '0' || scope.row.menuType === 0">目录</el-tag>
              <el-tag type="primary" v-else-if="scope.row.menuType === '1' || scope.row.menuType === 1">菜单</el-tag>
              <el-tag type="success" v-else-if="scope.row.menuType === '2' || scope.row.menuType === 2">按钮</el-tag>
            </template>
          </el-table-column>
          <el-table-column prop="path" label="路由路径" min-width="150"></el-table-column>
          <el-table-column prop="component" label="组件路径" min-width="200"></el-table-column>
          <el-table-column prop="icon" label="菜单图标" width="100" align="center">
            <template #default="scope">
              <el-icon v-if="scope.row.icon">
                <component :is="iconComponents[scope.row.icon] || 'el-icon-' + scope.row.icon" />
              </el-icon>
              <span v-else>--</span>
            </template>
          </el-table-column>
          <el-table-column prop="menuKey" label="权限标识" min-width="150"></el-table-column>
          <el-table-column prop="orderNum" label="排序" width="80" align="center"></el-table-column>
          <el-table-column prop="status" label="状态" width="80" align="center">
            <template #default="scope">
              <el-switch 
                v-model="scope.row.status" 
                active-value="1" 
                inactive-value="0" 
                @change="handleStatusChange(scope.row)"
              ></el-switch>
            </template>
          </el-table-column>
          <el-table-column prop="createTime" label="创建时间" min-width="160"></el-table-column>
          <el-table-column label="操作" width="200" fixed="right" align="center">
            <template #default="scope">
              <el-button type="primary" size="small" @click="handleEditMenu(scope.row)">编辑</el-button>
              <el-button type="success" size="small" @click="handleAddSubMenu(scope.row)" :disabled="scope.row.menuType === '2' || scope.row.menuType === 2">添加子菜单</el-button>
              <el-button type="danger" size="small" @click="handleDeleteMenu(scope.row)" :disabled="hasChildren(scope.row)">删除</el-button>
            </template>
          </el-table-column>
        </el-tree-table>
      </div>
    </el-card>
    
    <!-- 菜单编辑对话框 -->
    <el-dialog v-model="dialogVisible" :title="dialogTitle" width="600px" :close-on-click-modal="false">
      <el-form ref="menuFormRef" :model="formData" :rules="formRules" label-width="100px">
        <el-form-item label="上级菜单" prop="parentId">
          <el-cascader 
            v-model="parentMenuPath"
            :options="menuTreeOptions"
            :props="{
              label: 'menuName',
              value: 'id',
              checkStrictly: true,
              expandTrigger: 'hover'
            }"
            placeholder="请选择上级菜单"
            :disabled="isEditingRoot"
            @change="handleParentMenuChange"
          ></el-cascader>
        </el-form-item>
        <el-form-item label="菜单名称" prop="menuName">
          <el-input v-model="formData.menuName" placeholder="请输入菜单名称"></el-input>
        </el-form-item>
        <el-form-item label="菜单类型" prop="menuType">
          <el-select v-model="formData.menuType" placeholder="请选择菜单类型" @change="handleMenuTypeChange">
            <el-option label="目录" value="0"></el-option>
            <el-option label="菜单" value="1"></el-option>
            <el-option label="按钮" value="2"></el-option>
          </el-select>
        </el-form-item>
        <el-form-item label="路由路径" prop="path" v-if="showPathField">
          <el-input v-model="formData.path" placeholder="请输入路由路径"></el-input>
        </el-form-item>
        <el-form-item label="组件路径" prop="component" v-if="showComponentField">
          <el-input v-model="formData.component" placeholder="请输入组件路径"></el-input>
        </el-form-item>
        <el-form-item label="菜单图标" prop="icon" v-if="showIconField">
          <el-select v-model="formData.icon" placeholder="请选择菜单图标">
            <el-option label="无" value=""></el-option>
            <el-option v-for="icon in availableIcons" :key="icon.value" :label="icon.label" :value="icon.value"></el-option>
          </el-select>
        </el-form-item>
        <el-form-item label="权限标识" prop="menuKey">
          <el-input v-model="formData.menuKey" placeholder="请输入权限标识"></el-input>
        </el-form-item>
        <el-form-item label="显示" prop="visible">
          <el-switch v-model="formData.visible" active-value="1" inactive-value="0"></el-switch>
        </el-form-item>
        <el-form-item label="排序" prop="orderNum">
          <el-input-number v-model="formData.orderNum" :min="0" :max="999" placeholder="请输入排序号"></el-input-number>
        </el-form-item>
        <el-form-item label="状态" prop="status">
          <el-switch v-model="formData.status" active-value="1" inactive-value="0"></el-switch>
        </el-form-item>
      </el-form>
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="dialogVisible = false">取消</el-button>
          <el-button type="primary" @click="submitForm">确定</el-button>
        </span>
      </template>
    </el-dialog>
  </div>
</template>

<script>
import { ref, reactive, onMounted, computed } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import * as icons from '@element-plus/icons-vue'

// 导入菜单相关API
import {
  getMenuList, 
  getMenuTree, 
  createMenu, 
  updateMenu, 
  deleteMenu,
  updateMenuStatus
} from '../../api/menu.js'

export default {
  name: 'MenuList',
  setup() {
    // 搜索表单
    const searchForm = reactive({
      menuName: '',
      menuType: '',
      status: ''
    })
    
    // 菜单树数据
    const menuTreeData = ref([])
    const menuTreeOptions = ref([])
    
    // 对话框状态
    const dialogVisible = ref(false)
    const dialogTitle = ref('新增菜单')
    
    // 表单数据
    const formData = reactive({
      id: '',
      parentId: '0',
      menuName: '',
      menuType: '0',
      path: '',
      component: '',
      icon: '',
      menuKey: '',
      visible: '1',
      orderNum: 0,
      status: '1'
    })
    
    // 父菜单路径（级联选择器使用）
    const parentMenuPath = ref([])
    
    // 表单验证规则
    const formRules = {
      menuName: [
        { required: true, message: '请输入菜单名称', trigger: 'blur' },
        { min: 1, max: 50, message: '菜单名称长度在 1 到 50 个字符', trigger: 'blur' }
      ],
      menuType: [
        { required: true, message: '请选择菜单类型', trigger: 'change' }
      ],
      path: [
        { required: true, message: '请输入路由路径', trigger: 'blur' },
        { min: 1, max: 200, message: '路由路径长度在 1 到 200 个字符', trigger: 'blur' }
      ],
      component: [
        { required: true, message: '请输入组件路径', trigger: 'blur' },
        { min: 1, max: 200, message: '组件路径长度在 1 到 200 个字符', trigger: 'blur' }
      ],
      orderNum: [
        { required: true, message: '请输入排序号', trigger: 'blur' },
        { type: 'number', min: 0, max: 999, message: '排序号在 0 到 999 之间', trigger: 'blur' }
      ],
      status: [
        { required: true, message: '请选择状态', trigger: 'change' }
      ]
    }
    
    // 表单引用
    const menuFormRef = ref(null)
    const menuTreeTableRef = ref(null)
    
    // 可用图标列表
    const availableIcons = ref([
      { value: 'Menu', label: '菜单 Menu' },
      { value: 'Folder', label: '目录 Folder' },
      { value: 'Operation', label: '按钮 Operation' },
      { value: 'User', label: '用户 User' },
      { value: 'Setting', label: '设置 Setting' },
      { value: 'Management', label: '管理 Management' },
      { value: 'Message', label: '消息 Message' },
      { value: 'Layout', label: '布局 Layout' },
      { value: 'More', label: '更多 More' },
      { value: 'Star', label: '星星 Star' },
      { value: 'Plus', label: '加 Plus' },
      { value: 'Minus', label: '减 Minus' },
      { value: 'Edit', label: '编辑 Edit' },
      { value: 'Delete', label: '删除 Delete' },
      { value: 'Search', label: '搜索 Search' },
      { value: 'Refresh', label: '刷新 Refresh' }
    ])
    
    // 图标组件映射
    const iconComponents = icons
    
    // 是否显示路径字段
    const showPathField = computed(() => {
      return formData.menuType === '0' || formData.menuType === '1' || formData.menuType === 0 || formData.menuType === 1
    })
    
    // 是否显示组件字段
    const showComponentField = computed(() => {
      return formData.menuType === '1' || formData.menuType === 1
    })
    
    // 是否显示图标字段
    const showIconField = computed(() => {
      return formData.menuType === '0' || formData.menuType === '1' || formData.menuType === 0 || formData.menuType === 1
    })
    
    // 是否正在编辑根节点
    const isEditingRoot = computed(() => {
      return formData.id && formData.parentId === '0'
    })
    
    // 加载菜单树
    const loadMenuTree = async () => {
      try {
        const response = await getMenuTree()
        if (response.code === 200) {
          menuTreeData.value = response.data
          menuTreeOptions.value = JSON.parse(JSON.stringify(response.data))
        } else {
          ElMessage.error(response.message || '获取菜单树失败')
        }
      } catch (error) {
        console.error('获取菜单树失败:', error)
        ElMessage.error('获取菜单树失败')
      }
    }
    
    // 搜索菜单
    const searchMenus = async () => {
      try {
        const params = {
          menuName: searchForm.menuName,
          menuType: searchForm.menuType,
          status: searchForm.status
        }
        const response = await getMenuList(params)
        if (response.code === 200) {
          menuTreeData.value = response.data
        } else {
          ElMessage.error(response.message || '获取菜单列表失败')
        }
      } catch (error) {
        console.error('获取菜单列表失败:', error)
        ElMessage.error('获取菜单列表失败')
      }
    }
    
    // 重置搜索条件
    const resetSearch = () => {
      searchForm.menuName = ''
      searchForm.menuType = ''
      searchForm.status = ''
      loadMenuTree()
    }
    
    // 检查是否有子菜单
    const hasChildren = (menu) => {
      return menu.children && menu.children.length > 0
    }
    
    // 打开新增菜单对话框
    const handleCreateMenu = () => {
      dialogTitle.value = '新增菜单'
      // 重置表单数据
      Object.keys(formData).forEach(key => {
        formData[key] = key === 'parentId' || key === 'visible' || key === 'status' ? '1' : 
                       key === 'orderNum' ? 0 : ''
      })
      formData.parentId = '0'
      parentMenuPath.value = []
      dialogVisible.value = true
    }
    
    // 添加子菜单
    const handleAddSubMenu = (parentMenu) => {
      dialogTitle.value = '添加子菜单'
      // 重置表单数据
      Object.keys(formData).forEach(key => {
        formData[key] = key === 'parentId' || key === 'visible' || key === 'status' ? '1' : 
                       key === 'orderNum' ? 0 : ''
      })
      formData.parentId = parentMenu.id.toString()
      parentMenuPath.value = [parentMenu.id]
      dialogVisible.value = true
    }
    
    // 打开编辑菜单对话框
    const handleEditMenu = (menu) => {
      dialogTitle.value = '编辑菜单'
      // 复制菜单数据到表单
      Object.assign(formData, {
        id: menu.id,
        parentId: menu.parentId.toString(),
        menuName: menu.menuName,
        menuType: menu.menuType.toString(),
        path: menu.path || '',
        component: menu.component || '',
        icon: menu.icon || '',
        menuKey: menu.menuKey || '',
        visible: menu.visible.toString(),
        orderNum: menu.orderNum || 0,
        status: menu.status.toString()
      })
      
      // 设置父菜单路径
      if (formData.parentId !== '0') {
        parentMenuPath.value = [formData.parentId]
      } else {
        parentMenuPath.value = []
      }
      
      dialogVisible.value = true
    }
    
    // 父菜单变化处理
    const handleParentMenuChange = (value) => {
      if (value && value.length > 0) {
        formData.parentId = value[value.length - 1]
      } else {
        formData.parentId = '0'
      }
    }
    
    // 菜单类型变化处理
    const handleMenuTypeChange = () => {
      if (formData.menuType === '2' || formData.menuType === 2) {
        formData.path = ''
        formData.component = ''
        formData.icon = ''
      }
    }
    
    // 提交表单
    const submitForm = async () => {
      if (!menuFormRef.value) return
      
      try {
        await menuFormRef.value.validate()
        
        const data = {
          ...formData,
          parentId: Number(formData.parentId),
          menuType: Number(formData.menuType),
          visible: Number(formData.visible),
          orderNum: Number(formData.orderNum),
          status: Number(formData.status)
        }
        
        let response
        if (formData.id) {
          // 更新菜单
          response = await updateMenu(data)
        } else {
          // 创建菜单
          response = await createMenu(data)
        }
        
        if (response.code === 200) {
          ElMessage.success(formData.id ? '更新菜单成功' : '创建菜单成功')
          dialogVisible.value = false
          loadMenuTree()
        } else {
          ElMessage.error(response.message || (formData.id ? '更新菜单失败' : '创建菜单失败'))
        }
      } catch (error) {
        console.error(formData.id ? '更新菜单失败:' : '创建菜单失败:', error)
        if (error?.message) {
          ElMessage.error(error.message)
        } else {
          ElMessage.error(formData.id ? '更新菜单失败' : '创建菜单失败')
        }
      }
    }
    
    // 删除菜单
    const handleDeleteMenu = (menu) => {
      if (hasChildren(menu)) {
        ElMessage.warning('请先删除子菜单')
        return
      }
      
      ElMessageBox.confirm(`确定要删除菜单 ${menu.menuName} 吗？`, '删除菜单', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(async () => {
        try {
          const response = await deleteMenu(menu.id)
          if (response.code === 200) {
            ElMessage.success('删除菜单成功')
            loadMenuTree()
          } else {
            ElMessage.error(response.message || '删除菜单失败')
          }
        } catch (error) {
          console.error('删除菜单失败:', error)
          ElMessage.error('删除菜单失败')
        }
      }).catch(() => {
        // 用户取消删除
      })
    }
    
    // 切换菜单状态
    const handleStatusChange = async (menu) => {
      try {
        const response = await updateMenuStatus(menu.id, menu.status)
        if (response.code === 200) {
          ElMessage.success(menu.status === '1' ? '启用菜单成功' : '禁用菜单成功')
        } else {
          // 恢复原来的状态
          menu.status = menu.status === '1' ? '0' : '1'
          ElMessage.error(response.message || (menu.status === '1' ? '启用菜单失败' : '禁用菜单失败'))
        }
      } catch (error) {
        // 恢复原来的状态
        menu.status = menu.status === '1' ? '0' : '1'
        console.error('更新菜单状态失败:', error)
        ElMessage.error('更新菜单状态失败')
      }
    }
    
    // 初始化加载
    onMounted(() => {
      loadMenuTree()
    })
    
    return {
      searchForm,
      menuTreeData,
      menuTreeOptions,
      dialogVisible,
      dialogTitle,
      formData,
      formRules,
      menuFormRef,
      menuTreeTableRef,
      availableIcons,
      iconComponents,
      parentMenuPath,
      showPathField,
      showComponentField,
      showIconField,
      isEditingRoot,
      searchMenus,
      resetSearch,
      hasChildren,
      handleCreateMenu,
      handleAddSubMenu,
      handleEditMenu,
      handleParentMenuChange,
      handleMenuTypeChange,
      submitForm,
      handleDeleteMenu,
      handleStatusChange
    }
  }
}
</script>

<style scoped>
.menu-list-container {
  padding: 20px;
}

.page-header {
  margin-bottom: 20px;
}

.page-header h2 {
  margin: 0 0 10px 0;
  font-size: 20px;
  font-weight: 600;
}

.page-header p {
  margin: 0;
  color: #606266;
}

.search-section {
  margin-bottom: 20px;
  padding: 15px 0;
}

.data-table {
  margin-bottom: 20px;
}

.tree-table-container {
  max-height: 600px;
  overflow-y: auto;
}

.el-tree-table {
  font-size: 14px;
}

.el-tree-table th {
  background-color: #f5f7fa !important;
  position: sticky;
  top: 0;
  z-index: 10;
}

.el-table .cell {
  white-space: nowrap;
}

.dialog-footer {
  display: flex;
  justify-content: flex-end;
  gap: 10px;
}
</style>